﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using Snowball.Common;
using System.IO.Compression;
using System.Windows.Forms;
using ShowScreen;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

namespace ToolsCXml
{
    public class CWeb
    {
        public CWeb()
        {
            OutCookies = "";
            strCookies = "";
            charset = "utf-8";
            charsettags = new BETags("[<head>-<title>][charset=->]");
        }

        public string GetOKUrl(string Url)
        {
            if (Url.StartsWith("https"))
            {
                return GetWebRequesthttps_Charset(ref charset, Url);
            }
            if(OutCookies=="")
            return GetWebRequest_Charset(ref charset, Url);
            return GetWebRequest_Charset(ref charset, Url, OutCookies);
        }

        private string GetWebRequesthttps_Charset(ref string charset, string url)
        {
            string txt;
            try
            {
                txt = GetWebRequesthttps(url, charset);
            }
            catch (Exception e)
            {
                if (e.Message.Contains("The hostname could not be parsed."))
                {
                    txt = GetWebClient(url);
                    return txt;
                }
                else if (e.Message.Contains("未能解析此远程名称:"))
                {
                    throw new Exception("没有联网，无法获取远程数据");
                }
                else
                    throw e;
            }
            return txt;
        }
        private string GetWebRequesthttps(string url, string charset)
        {
            Uri uri = new Uri(url);
            Util.SetCertificatePolicy();

            WebRequest myReq = WebRequest.Create(uri);
            WebResponse result = myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding(charset));
            string strHTML = readerOfStream.ReadToEnd();

            readerOfStream.Close();
            receviceStream.Close();
            result.Close();
            return strHTML;

        }

        private string GetWebRequest_Charset(ref string charset, string url, string OutCookies)
        {
            string txt;
            try
            {
                txt = GetWebRequest(url, charset,OutCookies);
            }
            catch (Exception e)
            {
                if (e.Message.Contains("The hostname could not be parsed."))
                {
                    txt = GetWebClient(url);
                    return txt;
                }
                else
                    throw e;
            }
            string cs = charsettags.Match(txt);
            if (cs == "")
            {
                charsettags = new BETags("[</title>-</head>][charset=->]");
                cs = charsettags.Match(txt).ToLower();
            }
            if (cs != "" && !cs.Contains(charset))
            {
                if (!DgvTools.ValidName(cs))
                {
                    if (cs.StartsWith("\""))
                        cs = cs.Substring(1, cs.IndexOf('\"') - 1);
                    if (cs.StartsWith("'"))
                        cs = cs.Substring(1, cs.IndexOf('\'') - 1);
                    if (cs.Contains("\""))
                        cs = cs.Substring(0, cs.IndexOf('\"'));
                    if (cs.Contains("'"))
                        cs = cs.Substring(0, cs.IndexOf('\''));
                    if (cs.EndsWith("/"))
                        cs = cs.Substring(0, cs.IndexOf('/')).Trim();

                }
                if (DgvTools.ValidName(cs))
                {
                    charset = cs;
                    txt = GetWebRequest(url, charset,OutCookies);
                }
            }
            return txt;
        }
        public string GetWebRequest_Charset(ref string charset, string url)
        {
            string txt ;
            try{
            	txt= GetWebRequest(url, charset);
            }catch(Exception e){
            	if(e.Message.Contains("The hostname could not be parsed.")){
            		txt = GetWebClient(url);
            		return txt;
            	}else
            	throw e;
            }
            string cs = charsettags.Match(txt);
            if (cs == "")
            {
                charsettags = new BETags("[</title>-</head>][charset=->]");
                cs = charsettags.Match(txt).ToLower();
            }
            if (cs!="" && !cs.Contains(charset))
            {
                if (!DgvTools.ValidName(cs))
                {
                    if (cs.StartsWith("\""))
                        cs = cs.Substring(1, cs.IndexOf('\"') - 1);
                    if (cs.StartsWith("'"))
                        cs = cs.Substring(1, cs.IndexOf('\'') - 1);
                    if (cs.Contains("\""))
                        cs = cs.Substring(0, cs.IndexOf('\"'));
                    if (cs.Contains("'"))
                        cs = cs.Substring(0, cs.IndexOf('\''));
                    if (cs.EndsWith("/"))
                        cs = cs.Substring(0,cs.IndexOf('/')).Trim();

                }
                if (DgvTools.ValidName(cs))
                {
                    charset = cs;
                    txt = GetWebRequest(url, charset);
                }
            }
            return txt;
        }
        public string GetHttpWebRequest(string url, out string strCookies)
        {
            Uri uri = new Uri(url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
            myReq.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
            myReq.Accept = "*/*";
            myReq.KeepAlive = true;
            myReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
            HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding("utf-8"));
            string strHTML = readerOfStream.ReadToEnd();
            readerOfStream.Close();
            receviceStream.Close();
            strCookies = FenxiCookie(result.Headers["Set-Cookie"]);
            result.Close();
            return strHTML;
        }
        public string GetHttpWebRequest(string url, string strCookies)
        {
            if (wl > 0)
            {
                strCookies += "WL=" + wl + ";";
            }
            Uri uri = new Uri(url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
            myReq.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
            myReq.Accept = "*/*";
            myReq.KeepAlive = true;
            myReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
            myReq.Headers.Add("Cookie", strCookies);
            HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding("utf-8"));
            string strHTML = readerOfStream.ReadToEnd();
            readerOfStream.Close();
            receviceStream.Close();
            wl = FenxiCookieWl(result.Headers["Set-Cookie"]);
            result.Close();
            return strHTML;
        }
        public string GetWebClient(string url)
        {
            string strHTML = "";
            WebClient myWebClient = new WebClient();
            Stream myStream = myWebClient.OpenRead(url);
            StreamReader sr = new StreamReader(myStream, System.Text.Encoding.GetEncoding("utf-8"));
            strHTML = sr.ReadToEnd();
            myStream.Close();
            return strHTML;
        }
        public string GetWebRequest(string url, string charset = "utf-8")
        {
            Uri uri = new Uri(url);
            WebRequest myReq = WebRequest.Create(uri);
            WebResponse result = myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding(charset));
            string strHTML = readerOfStream.ReadToEnd();

            readerOfStream.Close();
            receviceStream.Close();
            result.Close();
            return strHTML;
        }
        // For OutCookies
        private string GetWebRequest(string url, string charset = "utf-8", string OutCookies = "")
        {
            Uri uri = new Uri(url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);

            myReq.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
            myReq.Accept = "*/*";
            myReq.KeepAlive = true;
            myReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
            myReq.Headers.Add("Cookie",OutCookies);

            WebResponse result = myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding(charset));
            string strHTML = readerOfStream.ReadToEnd();

            readerOfStream.Close();
            receviceStream.Close();
            result.Close();
            return strHTML;
        }
        public int FenxiCookieWl(string cookie)
        {
            if (cookie == null)
                return this.wl;
            int wl = Convert.ToInt32(DgvTools.GetEqualValue(cookie, "WL=", ";"));
            return wl;
        }
        public string FenxiCookie(string cookie)
        {
            string ret = "jyean=" + DgvTools.GetEqualValue(cookie, "jyean=", ";") + ";";
            return ret;
        }
        public static string PostHtml(string url, ref string strCookies)
        {
            PostSubmitter post = new PostSubmitter();
            System.Net.ServicePointManager.Expect100Continue = false;
            post.Url = url;
            post.Type = PostSubmitter.PostTypeEnum.Post;
            // 加入cookies，必须是这么写，一次性添加是不正确的。
            post.strCookies = strCookies;
            string ret = post.Post();
            strCookies = post.strCookies;
            return ret;
        }
        public static void DownLoadFile(String url, String FileName, bool cookie = false) //,Form1 fm = null
        {
            try
            {
                if (cookie)
                {
                    HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);

                    myReq.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
                    myReq.Accept = "*/*";
                    myReq.KeepAlive = true;
                    myReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
                    myReq.Headers.Add("Cookie", CItem.web.OutCookies  );

                    myReq.Timeout = 3000;
                    WebResponse wr = (HttpWebResponse)myReq.GetResponse();
                    Stream httpStream = wr.GetResponseStream();
                    httpStream = DealStreamZip(wr, httpStream);

                    if (wr.Headers.AllKeys.Contains("Content-Disposition"))
                    {
                        string savename = wr.Headers["Content-Disposition"];
                        savename = System.Web.HttpUtility.UrlDecode(savename);
                        BETag be = new BETag("[filename=\"-\"]");

                        savename = be.BEPos(savename).String;
                        FileName = FileName + savename;
                    }
                    else
                    {
                        FileName = FileName + ".flv";
                    }
                    FileStream outputStream = new FileStream(FileName, FileMode.Create);
                    int bufferSize = 2048;
                    int readCount;
                    byte[] buffer = new byte[bufferSize];
                    readCount = httpStream.Read(buffer, 0, bufferSize);
                    while (readCount > 0)
                    {
                        outputStream.Write(buffer, 0, readCount);

                        readCount = httpStream.Read(buffer, 0, bufferSize);
                    }
                    httpStream.Close();
                    outputStream.Close();

                    //if (fm != null && fm._TestRun)
                    //{                      
                    //    fm.AppendDebugMsg("download-Newfilename", FileName);
                    //}
                }
                else
                {
                    FileStream outputStream = new FileStream(FileName, FileMode.Create);
                    WebRequest request = WebRequest.Create(url);
                    request.Timeout = 3000;
                    WebResponse wr = (HttpWebResponse)request.GetResponse();
                    Stream httpStream = wr.GetResponseStream();
                    httpStream = DealStreamZip(wr, httpStream);

                    int bufferSize = 2048;
                    int readCount;
                    byte[] buffer = new byte[bufferSize];
                    readCount = httpStream.Read(buffer, 0, bufferSize);
                    while (readCount > 0)
                    {
                        outputStream.Write(buffer, 0, readCount);

                        readCount = httpStream.Read(buffer, 0, bufferSize);
                    }
                    httpStream.Close();
                    outputStream.Close();
                }
            }
            catch (Exception ex)
            {
                FileStream outputStream = new FileStream(Application.StartupPath + @"\downloaderror.log", FileMode.Append);
                StreamWriter sw = new StreamWriter(outputStream);
                String s = url + "\t" + FileName + "\t 文件下载失败错误为" + ex.Message.ToString() + "\r\n";
                sw.Write(s);
                sw.Close();
                outputStream.Close();
                //return "";
                //MessageBox.Show("文件下载失败错误为" + ex.Message.ToString(), "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        public static Stream DealStreamZip(WebResponse wr, Stream httpStream)
        {
            if (wr.Headers["Content-Encoding"] == "gzip")//gzip解压处理
            {
                MemoryStream msTemp = new MemoryStream();
                GZipStream gzs = new GZipStream(httpStream, CompressionMode.Decompress);
                byte[] buf = new byte[1024];
                int len;
                while ((len = gzs.Read(buf, 0, buf.Length)) > 0)
                {
                    msTemp.Write(buf, 0, len);
                }
                msTemp.Position = 0;
                httpStream = msTemp;
            }
            else if (wr.Headers["Content-Encoding"] == "deflate")//gzip解压处理
            {
                MemoryStream msTemp = new MemoryStream();
                DeflateStream gzs = new DeflateStream(httpStream, CompressionMode.Decompress);
                byte[] buf = new byte[1024];
                int len;
                while ((len = gzs.Read(buf, 0, buf.Length)) > 0)
                {
                    msTemp.Write(buf, 0, len);
                }
                msTemp.Position = 0;
                httpStream = msTemp;
            }
            return httpStream;
        }

            /// <summary>  
    /// 指定Post地址使用Get 方式获取全部字符串  
    /// </summary>  
    /// <param name="url">请求后台地址</param>  
    /// <returns></returns>  
    	public static string Post(string url)  
    	{  
	        string result = "";  
	        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);  
	        req.Method = "POST";  
	        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  
	        Stream stream = resp.GetResponseStream();  
	        //获取内容  
	        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))  
	        {  
	            result = reader.ReadToEnd();  
	        }  
	        return result;  
    	}
        public string OutCookies { get; set; }
        public string strCookies;
        public int wl;

        private string charset;
        private BETags charsettags;
    }
    public static class Util
    {
        /// <summary>
        /// Sets the cert policy.
        /// </summary>
        public static void SetCertificatePolicy()
        {
            ServicePointManager.ServerCertificateValidationCallback
                       += RemoteCertificateValidate;
        }

        /// <summary>
        /// Remotes the certificate validate.
        /// </summary>
        private static bool RemoteCertificateValidate(
           object sender, X509Certificate cert,
            X509Chain chain, SslPolicyErrors error)
        {
            // trust any certificate!!!
            System.Console.WriteLine("Warning, trust any certificate");
            return true;
        }
    }
}
